import { Context } from 'koa';
import { AppContext } from '@/types';
import { Company } from '@/models';
import * as response from '@/utils/response';
import { validate, commonSchemas } from '@/utils/validator';
import logger from '@/utils/logger';
import Joi from 'joi';
import { Op } from 'sequelize';

/**
 * 公司管理控制器
 */
class CompanyController {
  /**
   * 获取公司列表
   */
  async list(ctx: Context) {
    const appCtx = ctx as AppContext;

    // 验证参数
    const schema = Joi.object({
      page: commonSchemas.page,
      pageSize: commonSchemas.pageSize,
      name: Joi.string().allow('').optional(),
      code: Joi.string().allow('').optional(),
      status: Joi.string().valid('active', 'inactive').allow('').optional(),
    });

    const params = await validate<any>(
      {
        page: ctx.query.page,
        pageSize: ctx.query.pageSize,
        name: ctx.query.name,
        code: ctx.query.code,
        status: ctx.query.status,
      },
      schema
    );

    const { page = 1, pageSize = 20, name, code, status } = params;

    try {
      // 构建查询条件
      const where: any = {
        tenantId: appCtx.state.user!.tenantId,
      };

      if (name) {
        where.name = { [Op.like]: `%${name}%` };
      }
      if (code) {
        where.code = { [Op.like]: `%${code}%` };
      }
      if (status) {
        where.status = status;
      }

      // 查询数据
      const { rows, count } = await Company.findAndCountAll({
        where,
        limit: pageSize,
        offset: (page - 1) * pageSize,
        order: [['createdAt', 'DESC']],
      });

      response.paginated(ctx, rows, count, page, pageSize);
    } catch (error) {
      logger.error('获取公司列表失败:', error);
      ctx.throw(500, '获取公司列表失败');
    }
  }

  /**
   * 获取公司详情
   */
  async get(ctx: Context) {
    const appCtx = ctx as AppContext;
    const { id } = ctx.params;

    try {
      const company = await Company.findOne({
        where: {
          id,
          tenantId: appCtx.state.user!.tenantId,
        },
      });

      if (!company) {
        return response.error(ctx, '公司不存在', 404);
      }

      response.success(ctx, company);
    } catch (error) {
      logger.error('获取公司详情失败:', error);
      ctx.throw(500, '获取公司详情失败');
    }
  }

  /**
   * 创建公司
   */
  async create(ctx: Context) {
    const appCtx = ctx as AppContext;

    // 验证参数
    const schema = Joi.object({
      name: Joi.string().required(),
      code: Joi.string().optional().allow(''),
      description: Joi.string().optional().allow(''),
      status: Joi.string().valid('active', 'inactive').default('active'),
    });

    const data = await validate<any>(ctx.request.body as any, schema);

    try {
      // 检查公司名称是否已存在
      const existingCompany = await Company.findOne({
        where: {
          tenantId: appCtx.state.user!.tenantId,
          name: data.name,
        },
      });

      if (existingCompany) {
        return response.error(ctx, '公司名称已存在', 400);
      }

      // 如果提供了 code，检查是否已存在
      if (data.code) {
        const existingCode = await Company.findOne({
          where: {
            tenantId: appCtx.state.user!.tenantId,
            code: data.code,
          },
        });

        if (existingCode) {
          return response.error(ctx, '公司编码已存在', 400);
        }
      }

      // 创建公司
      const company = await Company.create({
        ...data,
        tenantId: appCtx.state.user!.tenantId,
      });

      logger.info(`公司创建成功: ${company.name} by ${appCtx.state.user!.email}`);
      ctx.status = 201;
      response.success(ctx, company, '公司创建成功');
    } catch (error) {
      logger.error('创建公司失败:', error);
      ctx.throw(500, '创建公司失败');
    }
  }

  /**
   * 更新公司
   */
  async update(ctx: Context) {
    const appCtx = ctx as AppContext;
    const { id } = ctx.params;

    // 验证参数
    const schema = Joi.object({
      name: Joi.string().optional(),
      code: Joi.string().optional().allow(''),
      description: Joi.string().optional().allow(''),
      status: Joi.string().valid('active', 'inactive').optional(),
    });

    const data = await validate<any>(ctx.request.body as any, schema);

    try {
      const company = await Company.findOne({
        where: {
          id,
          tenantId: appCtx.state.user!.tenantId,
        },
      });

      if (!company) {
        return response.error(ctx, '公司不存在', 404);
      }

      // 检查名称是否已存在
      if (data.name && data.name !== company.name) {
        const existingCompany = await Company.findOne({
          where: {
            tenantId: appCtx.state.user!.tenantId,
            name: data.name,
            id: { [Op.ne]: id },
          },
        });

        if (existingCompany) {
          return response.error(ctx, '公司名称已存在', 400);
        }
      }

      // 检查编码是否已存在
      if (data.code && data.code !== company.code) {
        const existingCode = await Company.findOne({
          where: {
            tenantId: appCtx.state.user!.tenantId,
            code: data.code,
            id: { [Op.ne]: id },
          },
        });

        if (existingCode) {
          return response.error(ctx, '公司编码已存在', 400);
        }
      }

      // 更新公司
      await company.update(data);

      logger.info(`公司更新成功: ${company.name} by ${appCtx.state.user!.email}`);
      response.success(ctx, company, '公司更新成功');
    } catch (error) {
      logger.error('更新公司失败:', error);
      ctx.throw(500, '更新公司失败');
    }
  }

  /**
   * 删除公司
   */
  async delete(ctx: Context) {
    const appCtx = ctx as AppContext;
    const { id } = ctx.params;

    try {
      const company = await Company.findOne({
        where: {
          id,
          tenantId: appCtx.state.user!.tenantId,
        },
      });

      if (!company) {
        return response.error(ctx, '公司不存在', 404);
      }

      await company.destroy();

      logger.info(`公司删除成功: ${company.name} by ${appCtx.state.user!.email}`);
      response.success(ctx, null, '公司删除成功');
    } catch (error) {
      logger.error('删除公司失败:', error);
      ctx.throw(500, '删除公司失败');
    }
  }
}

export default new CompanyController();

